﻿using PageAdmin.Utils.ORM;
using PageAdmin.Utils.ORM.PropertyDescriptor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace PageAdmin.Utils.BLL
{
    /// <summary>
    /// 添加数据BLL
    /// </summary>
    public class AddBLL<T> : IAdd<T> where T : class, new()
    {
        /// <summary>
        /// 执行前的委托
        /// </summary>
        public Func<T, TipsInfo> Executing { get; set; }

        /// <summary>
        /// 执行后的委托
        /// </summary>
        public Func<T, TipsInfo> Executed { get; set; }

        /// <summary>
        /// 数据库对象
        /// </summary>
        private DataBaseContext _DbContext;


        public AddBLL(DataBaseContext dataBaseContext)
        {
            _DbContext = dataBaseContext;
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tModel"></param>
        /// <returns></returns>
        public TipsInfo Add(T tModel)
        {
            TipsInfo tipsInfo = new TipsInfo();
            try
            {
                int addId = 0;//新添加的数据id
                DbSet<T> dbSet = _DbContext.DbSet<T>();
                if (Executing != null)
                {
                    tipsInfo = Executing.Invoke(tModel); //执行前
                }
                if (tipsInfo.State == 1)
                {
                    addId = dbSet.Insert(tModel, GetLimitFields(dbSet));
                    if (addId<=0)
                    {
                        tipsInfo.State = 1;
                        tipsInfo.Msg = "添加失败!";
                        return tipsInfo;
                    }
                    SetIdPropety(dbSet, tModel, addId);//反射给Id赋值
                }
                if (tipsInfo.State == 1)
                {
                    tipsInfo = updateAttachmentState(dbSet, tModel, addId);
                }
                if (tipsInfo.State == 1)
                {
                    tipsInfo = SubdataBLL.AddOrEditSubdata(_DbContext,tModel, addId,"add");
                }
                if (tipsInfo.State == 1 && Executed != null)
                {
                    tipsInfo = Executed.Invoke(tModel);//执行后
                }
            }
            catch (Exception e)
            {
                tipsInfo.State = 0;
                tipsInfo.Msg = e.Message;
            }
            return tipsInfo;
        }

        /// <summary>
        /// 获取允许添加的字段
        /// </summary>
        /// <param name="dbSet"></param>
        /// <returns></returns>
        private IEnumerable<string> GetLimitFields(DbSet<T> dbSet)
        {
            IEnumerable<ModelFieldMapped> modelFieldMappedList = dbSet.ModelFieldMappingList.Where(c => c.AllowAdd==false);
            if (modelFieldMappedList.Count() <= 0)
            {
                return null;
            }
            return dbSet.ModelFieldMappingList.Where(c => c.AllowAdd == true).Select(c => c.FieldName);
        }


        /// <summary>
        /// 反射给Id属性赋值
        /// </summary>
        private void SetIdPropety(DbSet<T> dbSet, T tModel, int addId)
        {
            //查找Id属性，并赋值
            PropertyInfo proInfo = dbSet.ModelType.GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
            if (proInfo != null)
            {
                //用索引值设置属性值
                proInfo.SetValue(tModel, addId, null);
            }
        }


        /// <summary>
        /// 同步更新附件记录
        /// </summary>
        /// <returns></returns>
        private TipsInfo updateAttachmentState(DbSet<T> dbSet, T tModel, int newId)
        {
            return AttachmentDataBLL.UpdateAttachmentState(dbSet, tModel, newId);
        }

    }
}